package lablayer.view;

import javafx.scene.shape.Line;
import lablayer.model.LLNode;
import javafx.scene.Group;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import javafx.scene.input.MouseEvent;
import javafx.scene.Cursor;
import lablayer.view.stat.ViewLinkBuffer;
import lablayer.view.state.StateFactory;
import lablayer.view.state.StateInterface;
import lablayer.view.ViewComponent;
import lablayer.view.stat.ViewLinkComponentBuffer;
import lablayer.view.stat.ViewBoxBuffer;
import lablayer.model.ComponentFactory;
import lablayer.model.MathComponents.MathComponentFactory;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javafx.scene.layout.Panel;

/**
 * @author Darkness
 */

public class ViewLink extends ViewComponent {
    public var startX: Float;
    public var startY: Float;
    public var endX: Float;
    public var endY: Float;
    public var linkOpacity: Float = 0.5;
    var parentViewComponent: ViewComponent = null;
    var childViewComponent: ViewComponent = null;

    var moveX: Float;
    var moveY: Float;    

	init {
		this.component = ComponentFactory.createComponent(MathComponentFactory.createLink());
	}

    override public function create(): javafx.scene.Node {
        Group {
            cursor: Cursor.HAND
            content: [
                //main line
                Line {
                    startX: bind this.startX
                    startY: bind this.startY
                    endX: bind this.endX
                    endY: bind this.endY
                    opacity: bind this.linkOpacity
                },
                //parent marker
                Circle {
                    centerX: bind this.startX
                    centerY: bind this.startY
                    radius: 7
                    fill: Color.web("#FC9E19")
                    opacity: bind this.linkOpacity

                    onMousePressed: function(e: MouseEvent): Void {
                        if (this.parentViewComponent == null) {
                            this.moveX = this.startX;
                            this.moveY = this.startY;
                        }
                    }
                    onMouseDragged: function(e: MouseEvent): Void {
                        if (this.parentViewComponent == null) {
                            this.startX = moveX + e.dragX;
                            this.startY = moveY + e.dragY;
                        }
                    }
                    onMouseReleased: function(e: MouseEvent): Void {
                        if (this.isCreated() != true) {
                            var viewComponent: ViewComponent = ViewLinkComponentBuffer.
                                getViewComponent();
                            if (viewComponent != null) {
                                if (this.getChild() != null) {
                                    var link: ViewLink = ViewLink {
                                        startX: bind viewComponent.translateX
                                        startY: bind viewComponent.translateY
                                        endX: bind this.getChild().translateX
                                        endY: bind this.getChild().translateY
                                    }
                                    link.setParent(viewComponent);
                                    link.setChild(this.getChild());
                                    link.createLink();
                                    ViewBoxBuffer.getViewBox().addViewComponent(link);
                                } else {
                                    var link: ViewLink = ViewLink {
                                        startX: bind viewComponent.translateX
                                        startY: bind viewComponent.translateY
                                        endX: this.endX
                                        endY: this.endY
                                    }                                                        
                                    link.setParent(viewComponent);
                                    ViewBoxBuffer.getViewBox().addViewComponent(link);
                                }
                                ViewBoxBuffer.getViewBox().removeViewComponent(this);                            
                            }
                        }
                    }
                },                
                //child marker
                Circle {
                    centerX: bind this.endX
                    centerY: bind this.endY
                    radius: 7
                    fill: Color.web("#4BFF0F")
                    opacity: bind this.linkOpacity

                    onMousePressed: function(e: MouseEvent): Void {
                        if (this.childViewComponent == null) {
                            this.moveX = this.endX;
                            this.moveY = this.endY;
                        }
                    }
                    onMouseDragged: function(e: MouseEvent): Void {
                        if (this.childViewComponent == null) {
                            this.endX = moveX + e.dragX;
                            this.endY = moveY + e.dragY;
                        }
                    }
                    onMouseReleased: function(e: MouseEvent): Void {
                        if (this.isCreated() != true) {
                            var viewComponent: ViewComponent = ViewLinkComponentBuffer.
                                getViewComponent();
                            if (viewComponent != null) {
                                if (this.getParent() != null) {
                                    var link: ViewLink = ViewLink {
                                        startX: bind this.getParent().translateX
                                        startY: bind this.getParent().translateY
                                        endX: bind viewComponent.translateX
                                        endY: bind viewComponent.translateY
                                    }
                                    link.setParent(this.getParent());
                                    link.setChild(viewComponent);
                                    link.createLink();
                                    ViewBoxBuffer.getViewBox().addViewComponent(link);
                                } else {
                                    var link: ViewLink = ViewLink {
                                        startX: this.startX
                                        startY: this.startY
                                        endX: bind viewComponent.translateX
                                        endY: bind viewComponent.translateY
                                    }
                                    link.setChild(viewComponent);
                                    ViewBoxBuffer.getViewBox().addViewComponent(link);
                                }
                                ViewBoxBuffer.getViewBox().removeViewComponent(this);
                            }
                        }
                    }
                }
            ]

            onMouseEntered: function(e: MouseEvent): Void {
                if (StateFactory.getState().getStateId() == StateInterface.LINK_STATE) {
                    this.linkOpacity = 1.0;
                    this.toFront();
                }
            }
            onMouseExited: function(e: MouseEvent): Void {
                if (StateFactory.getState().getStateId() == StateInterface.LINK_STATE) {
                    var link: ViewLink = ViewLinkBuffer.getManageLink();
                    if ((link.equals(this)) != true) {
                        this.linkOpacity = 0.5;
                    }                    
                }
            }
            onMousePressed: function(e: MouseEvent): Void {
                if (StateFactory.getState().getStateId() == StateInterface.LINK_STATE) {
                    if (e.primaryButtonDown) {
                        var link: ViewLink = ViewLinkBuffer.getManageLink();
                        if (link.equals(this)) {
                            ViewLinkBuffer.clearManageLink();
                            this.linkOpacity = 0.5;
                        } else {
                            if (link != null) {
                                link.linkOpacity = 0.5;
                            }
                            ViewLinkBuffer.setManageLink(this);
                            this.linkOpacity = 1.0;
                        }
                    }
                    if (e.secondaryButtonDown) {
                        if (StateFactory.getState().getStateId() == StateInterface.LINK_STATE) {
                            var link: ViewLink = ViewLinkBuffer.getManageLink();
                            if (link != null) {
                                link.destroyLink();
                                ViewBoxBuffer.getViewBox().removeViewComponent(link);
                            }
                        }
                    }
                }
            }
        }
    }

    public function setParent(viewComponent: ViewComponent): Void {
        this.parentViewComponent = viewComponent;
    }

    public function setChild(viewComponent: ViewComponent): Void {
        this.childViewComponent = viewComponent;
    }

    public function getParent(): ViewComponent {
        return this.parentViewComponent;
    }

    public function getChild(): ViewComponent {
        return this.childViewComponent;
    }

    public function createLink(): Void {
        if ((this.parentViewComponent != null) and
        (this.childViewComponent != null)) {
            this.parentViewComponent.getComponent().
                add(this.childViewComponent.getComponent() as LLNode);
        }
    }

    public function destroyLink(): Void {
        if ((this.parentViewComponent != null) and
        (this.childViewComponent != null)) {
            this.parentViewComponent.getComponent().
                remove(this.childViewComponent.getComponent() as LLNode);
        }
    }    
    public function isCreated(): Boolean {                
        return this.parentViewComponent.getComponent().hasComponent(
            this.childViewComponent.getComponent() as LLNode);
    }

    override public function update(): Void {}

	override public function saveToXML(): String {
		var xml: String = "";

		xml += "	<ViewComponent>\r\n";
		xml += "		<Type>{this.component.getComponentId()}</Type>\r\n";
		xml += "		<StartX>{this.startX}</StartX>\r\n";
		xml += "		<StartY>{this.startY}</StartY>\r\n";
		xml += "		<EndX>{this.endX}</EndX>\r\n";
		xml += "		<EndY>{this.endY}</EndY>\r\n";
		if (this.parentViewComponent != null) {
			xml += "		<Parent>{this.parentViewComponent.getViewComponentId()}</Parent>\r\n";
		} else {
			xml += "		<Parent></Parent>\r\n";
		}
		if (this.childViewComponent != null) {
			xml += "		<Child>{this.childViewComponent.getViewComponentId()}</Child>\r\n";
		} else {
			xml += "		<Child></Child>\r\n";
		}
		xml += "		<ViewComponentId>{this.viewComponentId}</ViewComponentId>\r\n";
		xml += "	</ViewComponent>\r\n";
		return xml;
	}

	override public function loadFromXML(vcNode: Node): Void {
		if (vcNode != null) {
			if (vcNode.getNodeType() == Node.ELEMENT_NODE) {
				var vcElement: Element = vcNode as Element;
				var nodeList: NodeList;
				var elem: Element;

				for (i in [0..6]) {
					if (i == 0) nodeList = vcElement.getElementsByTagName("StartX");
					if (i == 1) nodeList = vcElement.getElementsByTagName("StartY");
					if (i == 2) nodeList = vcElement.getElementsByTagName("EndX");
					if (i == 3) nodeList = vcElement.getElementsByTagName("EndY");
					if (i == 4) nodeList = vcElement.getElementsByTagName("Parent");
					if (i == 5) nodeList = vcElement.getElementsByTagName("Child");
					if (i == 6) nodeList = vcElement.getElementsByTagName("ViewComponentId");
					elem = nodeList.item(0) as Element;
					var str: String = elem.getChildNodes().item(0).getNodeValue();
					if (i == 0) {
						this.startX = Float.parseFloat(str);
					}
					if (i == 1) {
						this.startY = Float.parseFloat(str);
					}
					if (i == 2) {
						this.endX = Float.parseFloat(str);
					}
					if (i == 3) {
						this.endY = Float.parseFloat(str);
					}
					if (i == 4) {
						if (str.equals("") != true) {
							var mainPanel: Panel = ViewBoxBuffer.getViewBox().getMainPanel();
							for (p in mainPanel.content) {
								if (p instanceof ViewComponent) {
									var vc: ViewComponent = p as ViewComponent;
									if (vc.getViewComponentId().equals(str)) {
										this.setParent(vc);
										break;
									}
								}
							}
						}
					}
					if (i == 5) {
						if (str.equals("") != true) {
							var mainPanel: Panel = ViewBoxBuffer.getViewBox().getMainPanel();
							for (p in mainPanel.content) {
								if (p instanceof ViewComponent) {
									var vc: ViewComponent = p as ViewComponent;
									if (vc.getViewComponentId().equals(str)) {
										this.setChild(vc);
										break;
									}
								}
							}
						}
					}
					if (i == 6) {
						this.viewComponentId = str;
					}
				}
			}
		}
	}

	
}